package sv.com.renacempleo.dao.red;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;

import sv.com.renacempleo.dao.BaseDaoImpl;
import sv.com.renacempleo.dto.red.RedOfertaConocimiento;
import sv.com.renacempleo.dto.red.RedOfertaFormacionAcademica;
import sv.com.renacempleo.dto.red.RedOfertaHabilidad;
import sv.com.renacempleo.dto.red.RedOfertaHorario;
import sv.com.renacempleo.dto.red.RedOfertaIdioma;
import sv.com.renacempleo.dto.red.RedOfertaSucursales;
import sv.com.renacempleo.exception.WebException;
import sv.com.renacempleo.web.controller.objects.RedOfertaForm;
import sv.com.renacempleo.web.util.WebUtilidades;

public class RedOfertaDaoImpl extends BaseDaoImpl implements RedOfertaDao{
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> findByIdAsMap(Long redOfertaId) throws WebException{
		String hqlQuery = WebUtilidades.getQueryByName("redOferta.findById");
		if(redOfertaId == null) redOfertaId = 0L;
		try {
			List<Object[]> list = (List<Object[]>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
			if(WebUtilidades.isEmptyList(list)) return null;
			return toMap(list.get(0), new String[]{
				"redOfertaId",
			 	"redOfertaFecha",
			 	"redOfertaActivo",
			 	"ctgOficinaId",
			 	"ctgEmpleadoId",
			 	"redEmpresaFolio"
			});
		} catch (Exception e) {
			logger.error(e, e);
			throw new WebException("Problemas a tratar de obtener la informaci\u00F3n");
		}
	}
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> findRedOfertaDatosByRedOfertaIdAsMap(Long redOfertaId) throws WebException{
		String hqlQuery = WebUtilidades.getQueryByName("redOfertaDatos.findByRedOfertaId");
		if(redOfertaId == null) redOfertaId = 0L;
		try {
			List<Object[]> list = (List<Object[]>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
			if(WebUtilidades.isEmptyList(list)) return null;
			return toMap(list.get(0), new String[]{
				"redOfertaDatoId",
				"redOfertaDatoPuesto",
				"redOfertaDatoCantidadPlazas",
				"redOfertaDatoSalario",
				"redOfertaDatoPeriodicidadPago",
				"redOfertaDatoTiempoPrueba",
				"redOfertaDatoDiscapacidad",
				"redOfertaDatoDescripcion",
				"redOfertaDatoFunciones",
				"redOfertaDatoPeriodoPrueba",
				"redOfertaDatoFormaContratacion",
				"ctgOcupacionId",
				"ctgJornadaLaboralId",
				"ctgFormaPagoId"
			});
		} catch (Exception e) {
			logger.error(e, e);
			throw new WebException("Problemas a tratar de obtener la informaci\u00F3n");
		}
	}
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> findRedOfertaRequisitosByRedOfertaIdAsMap(Long redOfertaId) throws WebException{
		String hqlQuery = WebUtilidades.getQueryByName("redOfertaRequisito.findByRedOfertaId");
		if(redOfertaId == null) redOfertaId = 0L;
		try {
			List<Object[]> list = (List<Object[]>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
			if(WebUtilidades.isEmptyList(list)) return null;
			return toMap(list.get(0), new String[]{
				"redOfertaRequisitoId",
				"redOfertaRequisitoExperiencia",
				"redOfertaRequisitoEdadIndiferente",
				"redOfertaRequisitoEdadMinima",
				"redOfertaRequisitoEdadMaxima",
				"redOfertaRequisitoGeneroIndiferente",
				"redOfertaRequisitoCarateristicasPersonales",
				"redOfertaRequisitoLicencia",
				"redOfertaRequisitoVehiculo",
				"redOfertaRequisitoAnioVehiculo",
				"ctgEstadoCivilId",
				"ctgGeneroId",
				"ctgTipoLicenciaId",
				"ctgTipoVehiculoId",
				"ctgIncorporacionId"
			});
		} catch (Exception e) {
			logger.error(e, e);
			throw new WebException("Problemas a tratar de obtener la informaci\u00F3n");
		}
	}
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> findRedOfertaDatosEntrevistaByRedOfertaIdAsMap(Long redOfertaId) throws WebException{
		String hqlQuery = WebUtilidades.getQueryByName("redOfertaDatosEntrevista.findByRedOfertaId");
		if(redOfertaId == null) redOfertaId = 0L;
		try {
			List<Object[]> list = (List<Object[]>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
			if(WebUtilidades.isEmptyList(list)) return null;
			return toMap(list.get(0), new String[]{
				"redOfertaDatosEntrevistaId",
				"redOfertaDatoEntrevistaLugarActividades",
				"redOfertaDatoEntrevistaLugarEntrevista",
				"redOfertaDatoEntrevistaEntrevistador",
				"redOfertaDatoEntrevistaTelefono",
				"redOfertaDatoEntrevistaCargo",
				"redOfertaDatoEntrevistaEmail",
				"redOfertaDatoEntrevistaHora",
				"redOfertaDatoEntrevistaDia",
				"redOfertaDatoEntrevistaObservaciones"
			});
		} catch (Exception e) {
			logger.error(e, e);
			throw new WebException("Problemas a tratar de obtener la informaci\u00F3n");
		}
	}
	
	@SuppressWarnings("unchecked")
	public List<Object[]> findRedPrestacionesByRedOfertaId(Long redOfertaId){
		String hqlQuery = WebUtilidades.getQueryByName("redOfertaPrestaciones.findAllByRedOfertaId");
		if(redOfertaId == null) redOfertaId = 0L;
		try {
			return (List<Object[]>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object[]> findRedDocumentosByRedOfertaId(Long redOfertaId){
		String hqlQuery = WebUtilidades.getQueryByName("redOfertaDocumentos.findAllByRedOfertaId");
		if(redOfertaId == null) redOfertaId = 0L;
		try {
			return (List<Object[]>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object[]> findRedOfertaOtrosRequisitosByRedOfertaId(Long redOfertaId){
		String hqlQuery = WebUtilidades.getQueryByName("redOfertaOtrosRequisitos.findAllByRedOfertaId");
		if(redOfertaId == null) redOfertaId = 0L;
		try {
			return (List<Object[]>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object[]> findRedOfertaDisponibilidadByRedOfertaId(Long redOfertaId){
		String hqlQuery = WebUtilidades.getQueryByName("redOfertaDisponibilidad.findAllByRedOfertaId");
		if(redOfertaId == null) redOfertaId = 0L;
		try {
			return (List<Object[]>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}

	@SuppressWarnings("unchecked")
	public List<Object[]> findBy(RedOfertaForm redOfertaForm){
		try{
			String hqlQuery = WebUtilidades.getQueryByName("redOferta.findBy");
			List<Object> params = new ArrayList<Object>();
			String where = "";
			boolean and = false;
			if("1".equals(redOfertaForm.getRedOfertaOrigen())){
				where += (and ? " and " : "");
				where += "redOferta.sgdUsuario.sgdUsuarioId = ?";
				params.add(WebUtilidades.getSgdUsuarioFromAcegi().getSgdUsuarioId());
				and = true;
			}else if("2".equals(redOfertaForm.getRedOfertaOrigen())){
				where += (and ? " and " : "");
				where += "redOferta.ctgOficinas.ctgOficinaId = ?";
				params.add(WebUtilidades.getSgdUsuarioFromAcegi().getCtgOficina().getCtgOficinaId());
				and = true;
			}
			if("1".equals(redOfertaForm.getRedOfertaEstado())){
				where += (and ? " and " : "");
				where += "redOferta.redOfertaActivo = '1'";
				and = true;
			}else if("1".equals(redOfertaForm.getRedOfertaEstado())){
				where += (and ? " and " : "");
				where += "redOferta.redOfertaActivo = '0'";
				and = true;
			}
			hqlQuery = StringUtils.replace(hqlQuery, "{WHERE}", StringUtils.isBlank(where) ? "" : (" where " + where));
			return (List<Object[]>) findByHQLQuery(hqlQuery, params.toArray());
		}catch (Exception e){
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> findRedOfertaFormacionAcademicaByRedOfertaId(Long redOfertaId){
		DetachedCriteria criteria = DetachedCriteria.forClass(RedOfertaFormacionAcademica.class);
		criteria.add(Restrictions.eq("redOferta.redOfertaId", redOfertaId));
		criteria.createAlias("ctgEscolaridad", "ctgEscolaridad");
		criteria.createAlias("ctgEspecialidad", "ctgEspecialidad");
		criteria.setProjection(Projections.projectionList()
			.add(Projections.property("redOfertaFormacionAcademicaId"))
			.add(Projections.property("ctgEscolaridad.ctgCatalogoNombre"))
			.add(Projections.property("ctgEspecialidad.ctgCatalogoNombre"))
		);
		criteria.addOrder(Order.asc("redOfertaFormacionAcademicaId"));
		try {
			return (List<Object>) findByCriteria(criteria);
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> findRedOfertaIdiomaByRedOfertaId(Long redOfertaId){
		DetachedCriteria criteria = DetachedCriteria.forClass(RedOfertaIdioma.class);
		criteria.add(Restrictions.eq("redOferta.redOfertaId", redOfertaId));
		criteria.createAlias("ctgIdioma", "ctgIdioma");
		criteria.createAlias("ctgNivel", "ctgNivel");
		criteria.setProjection(Projections.projectionList()
				.add(Projections.property("redOfertaIdiomaId"))
				.add(Projections.property("ctgIdioma.ctgCatalogoNombre"))
				.add(Projections.property("ctgNivel.ctgCatalogoNombre"))
		);
		criteria.addOrder(Order.asc("redOfertaIdiomaId"));
		try {
			return (List<Object>) findByCriteria(criteria);
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> findRedOfertaConocimientoByRedOfertaId(Long redOfertaId){
		DetachedCriteria criteria = DetachedCriteria.forClass(RedOfertaConocimiento.class);
		criteria.add(Restrictions.eq("redOferta.redOfertaId", redOfertaId));
		criteria.createAlias("ctgAreaConocmiento", "ctgAreaConocmiento");
		criteria.createAlias("ctgDetalleAreasConocimiento", "ctgDetalleAreasConocimiento");
		criteria.setProjection(Projections.projectionList()
				.add(Projections.property("redOfertaConocimientoId"))
				.add(Projections.property("ctgAreaConocmiento.ctgCatalogoNombre"))
				.add(Projections.property("ctgDetalleAreasConocimiento.ctgDetalleAreaConocimientoDescripcion"))
		);
		criteria.addOrder(Order.asc("redOfertaConocimientoId"));
		try {
			return (List<Object>) findByCriteria(criteria);
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> findRedOfertaHabilidadByRedOfertaId(Long redOfertaId){
		DetachedCriteria criteria = DetachedCriteria.forClass(RedOfertaHabilidad.class);
		criteria.add(Restrictions.eq("redOferta.redOfertaId", redOfertaId));
		criteria.createAlias("ctgHabilidad", "ctgHabilidad");
		criteria.createAlias("ctgDetalleHabilidades", "ctgDetalleHabilidades");
		criteria.setProjection(Projections.projectionList()
				.add(Projections.property("redOfertaHabilidadId"))
				.add(Projections.property("ctgHabilidad.ctgCatalogoNombre"))
				.add(Projections.property("ctgDetalleHabilidades.ctgDetalleHabilidadDescripcion"))
		);
		criteria.addOrder(Order.asc("redOfertaHabilidadId"));
		try {
			return (List<Object>) findByCriteria(criteria);
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> findRedOfertaSucursalesByRedOfertaId(Long redOfertaId){
		DetachedCriteria criteria = DetachedCriteria.forClass(RedOfertaSucursales.class);
		criteria.add(Restrictions.eq("redOferta.redOfertaId", redOfertaId));
		criteria.createAlias("ctgDepartamento", "ctgDepartamento", Criteria.LEFT_JOIN);
		criteria.createAlias("ctgMunicipio", "ctgMunicipio", Criteria.LEFT_JOIN);
		criteria.setProjection(Projections.projectionList()
			.add(Projections.property("redOfertaSucursalId"))
			.add(Projections.property("redOfertaSucursalNombre"))
			.add(Projections.property("redOfertaSucursalOficina"))
			.add(Projections.property("redOfertaSucursalDireccion"))
			.add(Projections.property("redOfertaSucursalTelefono"))
			.add(Projections.property("redOfertaSucursalFax"))
			.add(Projections.property("redOfertaSucursalEmail"))
			.add(Projections.property("ctgDepartamento.ctgDepartamentoId"))
			.add(Projections.property("ctgDepartamento.ctgDepartamentoNombre"))
			.add(Projections.property("ctgMunicipio.ctgMunicipioId"))
			.add(Projections.property("ctgMunicipio.ctgMunicipioNombre"))
		);
		criteria.addOrder(Order.asc("redOfertaSucursalId"));
		try {
			return (List<Object>) findByCriteria(criteria);
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> findRedOfertaContactoByRedOfertaId(Long redOfertaId){
		String hqlQuery = WebUtilidades.getQueryByName("redOfertaContacto.findRedOfertaContactoByRedOfertaId");
		try {
			return (List<Object>) findByHQLQuery(hqlQuery, new Object[]{redOfertaId});
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
	
	@SuppressWarnings("unchecked")
	public List<Object> findRedOfertaHorarioByRedOfertaId(Long redOfertaId){
		DetachedCriteria criteria = DetachedCriteria.forClass(RedOfertaHorario.class);
		criteria.add(Restrictions.eq("redOferta.redOfertaId", redOfertaId));
		criteria.setProjection(Projections.projectionList()
			.add(Projections.property("redOfertaHorarioId"))
			.add(Projections.property("redOfertaHorarioDiaInicio"))
			.add(Projections.property("redOfertaHorarioHoraInicio"))
			.add(Projections.property("redOfertaHorarioInicioAmPm"))
			.add(Projections.property("redOfertaHorarioDiaFin"))
			.add(Projections.property("redOfertaHorarioHoraFin"))
			.add(Projections.property("redOfertaHorarioFinAmPm"))
		);
		criteria.addOrder(Order.asc("redOfertaHorarioId"));
		try {
			return (List<Object>) findByCriteria(criteria);
		} catch (WebException e) {
			logger.error(e, e);
		}
		return Collections.emptyList();
	}
}
